package cn.fintecher.pangolin.service.dataimp.task;

import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.*;
import cn.fintecher.pangolin.service.dataimp.elastic.BaseCaseElastic;
import cn.fintecher.pangolin.service.dataimp.model.ImportCommonModel;
import cn.fintecher.pangolin.service.dataimp.model.ImportModel;
import cn.fintecher.pangolin.service.dataimp.request.ImportCaseRequest;
import cn.fintecher.pangolin.service.dataimp.service.BaseService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 15:03 2019/11/5
 */

@Service("importCaseFuture")
public class ImportCaseFuture {
    private static final Logger log = LoggerFactory.getLogger(ImportCaseFuture.class);

    @Autowired
    private BaseService baseService;

    @Autowired
    private BaseCaseElastic baseCaseElastic;

    /**
     * 多线程处理excel数据
     *
     * @param mapList        分页数据map对象
     * @param sheetIndex     sheet页编号
     * @param batchNumber    批次号
     * @param itemMap        模板配置项
     * @param num            数据行
     * @param request        案件导入请求参数
     * @param record         案件导入结果checkout
     * @param importTemplate 导入模板
     * @param titleMap       表头数据
     * @return 案件导入模型集合
     */
    @Async
    public CompletableFuture<List<ImportModel>> processExcel(List<Map<String, String>> mapList, int sheetIndex, String batchNumber, Map<String,
            ImportTemplateItem> itemMap, Integer num, ImportCaseRequest request, DataImportRecord record, ImportTemplate importTemplate, Map<String, String> titleMap) {
        int row = importTemplate.getDataStartRow() + num;
        List<ImportModel> models = new ArrayList<>();
        for (Map<String, String> map : mapList) {
            ImportModel model = new ImportModel();
            PersonalImportModel personalImportModel = new PersonalImportModel();
            CaseImportModel caseImportModel = new CaseImportModel();
            ImportCommonModel importCommonModel = new ImportCommonModel();
            importCommonModel.setCaseImportModel(caseImportModel);
            importCommonModel.setPersonalImportModel(personalImportModel);
            importCommonModel.setFlag(0);
            List<String> errors = new ArrayList<>();
            for (Map.Entry<String, ImportTemplateItem> entry : itemMap.entrySet()) {
                baseService.rowToObj(importCommonModel, entry, map, row, errors, sheetIndex);
            }
            if (Objects.isNull(caseImportModel.getLeftAmt()) || caseImportModel.getLeftAmt().equals(0d)) {
                caseImportModel.setLeftAmt(caseImportModel.getOverdueAmtTotal());
            } else {
                if (caseImportModel.getLeftAmt() > 0d) {
                    caseImportModel.setLeftAmt(caseImportModel.getLeftAmt());
                } else {
                    caseImportModel.setLeftAmt(caseImportModel.getOverdueAmtTotal());
                }
            }
            List<UnMappedValue> unMapped = new ArrayList<>();
            //处理未匹配字段
            if (Objects.nonNull(titleMap)) {
                unMapped = processUnmapped(map, titleMap, row, errors);
            }
            caseImportModel.setDelegationDate(request.getCommissionDate()); //委案日期
            caseImportModel.setEndCaseDate(request.getEndDate()); //结案日期
            //必填字段判空
            Double overdueAmtTotal = caseImportModel.getOverdueAmtTotal();
            if (Objects.isNull(overdueAmtTotal)) {
                errors.add("第【" + row + "】行中的数据【委案金额】对应值为空");
            }
            String name = personalImportModel.getName();
            if (StringUtils.isBlank(name)) {
                errors.add("第【" + row + "】行中的数据【姓名】对应值为空");
            }
            String certificateNo = personalImportModel.getCertificateNo();
            if (StringUtils.isBlank(certificateNo)) {
                errors.add("第【" + row + "】行中的数据【证件号】对应值为空");
            }
            String caseNumber = caseImportModel.getCaseNumber();
            if (StringUtils.isBlank(caseNumber)) {
                errors.add("第【" + row + "】行中的数据【案件编号】对应值为空");
            } else {
                //案件编号重复判断
                BoolQueryBuilder builder = new BoolQueryBuilder();
                try {
                    builder.must(QueryBuilders.matchPhraseQuery("caseNumber.keyword", caseImportModel.getCaseNumber()));
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    errors.add("请确认导入模板是否正确,当前导入类型是案件导入");
                }
                Iterable<BaseCase> iterable = baseCaseElastic.search(builder);
                if (iterable.iterator().hasNext()) {
                    errors.add("第【" + row + "】行中的数据【" + caseImportModel.getCaseNumber() + "】作为案件编号时在系统中已存在");
                }
                personalImportModel.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                personalImportModel.setPrincipalId(record.getPrincipalId()); //委托方ID
                personalImportModel.setPrincipalName(record.getPrincipalName()); //委托方名称
                personalImportModel.setBatchNumber(batchNumber); //批次号
                personalImportModel.setModel(caseImportModel); //合同信息模型
                personalImportModel.setUnMapped(unMapped); //未匹配字段
            }
            model.setPersonalImportModel(personalImportModel);
            model.setErrors(errors);
            models.add(model);
            row++;
        }
        return CompletableFuture.completedFuture(models);
    }

    private List<UnMappedValue> processUnmapped(Map<String, String> dataMap, Map<String, String> titleMap, int row, List<String> errors) {
        List<UnMappedValue> map = new ArrayList<>();
        for (Map.Entry<String, String> entry : dataMap.entrySet()) {
            String str = entry.getValue();
            if (StringUtils.isNotBlank(str)) {
                try {
                    Date date = ZWDateUtil.getUtilDate(str);
                    UnMappedValue un = new UnMappedValue();
                    if (Objects.nonNull(date)) {
                        un.setKey(titleMap.get(entry.getKey()));
                        un.setValue(ZWDateUtil.fomratterDate(date, "yyyy年MM月dd日"));
                        map.add(un);

                    } else {
                        un.setKey(titleMap.get(entry.getKey()));
                        un.setValue(str);
                        map.add(un);
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    errors.add("第【" + row + "】行中的数据【" + str + "】不是正规的日期格式");
                }
            } else {
                UnMappedValue un = new UnMappedValue();
                un.setKey(titleMap.get(entry.getKey()));
                un.setValue("");
                map.add(un);

            }
        }
        return map;
    }
}
